package com.clementheliou.cheliou.web.core.i18n.validation.interpolator;

import static javax.faces.context.FacesContext.getCurrentInstance;
import static org.springframework.web.jsf.FacesContextUtils.getRequiredWebApplicationContext;

import java.util.Locale;

import javax.validation.MessageInterpolator;

import org.springframework.context.MessageSource;

import com.clementheliou.cheliou.web.controller.user.UserBean;

/**
 * Custom {@link MessageInterpolator} based on Spring {@link MessageSource}. It
 * can be used to override the default behavior of the Hibernate validator.
 * 
 * @author Clément HELIOU (clement.heliou@gmail.com)
 * @see {@link MessageInterpolator};
 * @see {@link MessageSource}.
 * @since 1.0
 */
public class SpringMessageSourceInterpolator implements MessageInterpolator {

	/**
	 * The message source that will be used in this interporlator to resolve the
	 * messages keys.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @see {@link MessageSource}.
	 * @since 1.0
	 */
	private MessageSource messageSource;

	/**
	 * Utilities about the user details. It will be used in this interpolator to
	 * determinated which locale should be used.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @see {@link UserBean}.
	 * @since 1.0
	 */
	private UserBean userBean;

	/**
	 * <i>{@inheritDoc}</i>
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @since 1.0
	 */
	@Override
	public String interpolate(String messageTemplate, Context context) {
		return interpolate(messageTemplate, context, getUserBean().getCurrentLocale());
	}

	/**
	 * <i> {@inheritDoc} </i>
	 * <p>
	 * The message resolution is delegated to the message source. If the key
	 * can't be found in the basenames, it's returned. Then, we avoid
	 * {@link Exception}'s that will hard to detect in an Ajax context.
	 * </p>
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @since 1.0
	 */
	@Override
	public String interpolate(String messageTemplate, Context context, Locale locale) {
		return getMessageSource().getMessage(messageTemplate, null, locale);
	}

	/*
	 * Getters & setters.
	 */

	private MessageSource getMessageSource() {
		if (null == messageSource) {
			messageSource = getRequiredWebApplicationContext(getCurrentInstance()).getBean(MessageSource.class);
		}
		return messageSource;
	}

	private UserBean getUserBean() {
		if (null == userBean) {
			userBean = getRequiredWebApplicationContext(getCurrentInstance()).getBean(UserBean.class);
		}
		return userBean;
	}

}
